﻿using System;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using System.Web.Caching;
using System.IO.Compression;
using System.ComponentModel;
using System.Net;
using System.Xml;


namespace DalatCooking.Core.Web.HttpHandlers
{
    public class ProxyHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        public void ProcessRequest(HttpContext context)
        {
            string url = context.Request["url"];
            int cacheDuration = Convert.ToInt32(context.Request["cache"] ?? "0");
            string contentType = context.Request["type"];

            // We don't want to buffer because we want to save memory
            context.Response.Buffer = false;

            // Serve from cache if available
            if (context.Cache[url] != null)
            {
                context.Response.BinaryWrite(context.Cache[url] as byte[]);
                context.Response.Flush();
                return;
            }
            using (WebClient client = new WebClient())
            {
                if (!string.IsNullOrEmpty(contentType))
                    client.Headers["Content-Type"] = contentType;

                client.Headers["Accept-Encoding"] = "gzip";
                client.Headers["Accept"] = "*/*";
                client.Headers["Accept-Language"] = "en-US";
                client.Headers["User-Agent"] =
                       "Mozilla/5.0 (Windows; U; Windows NT 6.0; " +
                       "en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6";

                byte[] data = client.DownloadData(url);

                context.Cache.Insert(url, data, null,
                            Cache.NoAbsoluteExpiration,
                            TimeSpan.FromMinutes(cacheDuration),
                            CacheItemPriority.Normal, null);

                if (!context.Response.IsClientConnected) return;


                // Deliver content type, encoding and length
                // as it is received from the external URL
                context.Response.ContentType =
                        client.ResponseHeaders["Content-Type"];
                string contentEncoding =
                       client.ResponseHeaders["Content-Encoding"];
                string contentLength =
                       client.ResponseHeaders["Content-Length"];

                if (!string.IsNullOrEmpty(contentEncoding))
                    context.Response.AppendHeader("Content-Encoding",
                                                  contentEncoding);
                if (!string.IsNullOrEmpty(contentLength))
                    context.Response.AppendHeader("Content-Length",
                                                  contentLength);

                if (cacheDuration > 0)
                    CacheResponse(context, cacheDuration);

                // Transmit the exact bytes downloaded
                context.Response.BinaryWrite(data);
            }

        }
        public static HttpWebRequest CreateScalableHttpWebRequest(string url)
        {
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Headers.Add("Accept-Encoding", "gzip");
            request.AutomaticDecompression = DecompressionMethods.GZip;
            request.MaximumAutomaticRedirections = 2;
            request.ReadWriteTimeout = 5000;
            request.Timeout = 3000;
            request.Accept = "*/*";
            request.Headers.Add("Accept-Language", "en-US");
            request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6";

            return request;
        }

        public static void CacheResponse(HttpContext context, int durationInMinutes)
        {
            TimeSpan duration = TimeSpan.FromMinutes(durationInMinutes);

            context.Response.Cache.SetCacheability(HttpCacheability.Public);
            context.Response.Cache.SetExpires(DateTime.Now.Add(duration));
            context.Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            context.Response.Cache.SetMaxAge(duration);
        }
        public static void DoNotCacheResponse(HttpContext context)
        {
            context.Response.Cache.SetNoServerCaching();
            context.Response.Cache.SetNoStore();
            context.Response.Cache.SetMaxAge(TimeSpan.Zero);
            context.Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            context.Response.Cache.SetExpires(DateTime.Now.AddYears(-1));
        }         
    }
}
